package com.alks.pad.commom.interceptor;


import com.alks.common.service.RedisService;
import com.alks.entity.exception.TokenErrorException;
import com.alks.pad.commom.date.dto.PadUserTokenDto;
import com.alks.pad.commom.date.thread.PadUserIdThread;
import com.alks.pad.commom.utils.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

@Slf4j
public class PadAuthenticateInterceptor implements HandlerInterceptor {
    @Autowired
    RedisService redisService;

    /*在执行Controller的任务之前判断是否有Session信息
      如果有Session信息就往下执行，去调用Controller。
      如果没有Session就跳转到登录页面
    */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        //TODO 暂时放行不能模拟携带token
        //获取请求头种的token
        String token = request.getHeader("Authorization");
        // 判空
        if (StringUtils.isEmpty(token)){
            log.warn("未携带token");
            throw new TokenErrorException("未携带token");
        }
        String tokenKey = redisService.get(token);
        if (tokenKey==null){
            log.warn("token已过期");
            throw new TokenErrorException("token已过期或者token错误");
        }

        //从Redis中获取的值tokenKe
        PadUserTokenDto userTokenDTO = JWTUtil.parseToken(tokenKey);
        String baseToken = userTokenDTO.getCollectUserName().toUpperCase() + "_" + "token";
        //给线程赋值
        PadUserIdThread.set(userTokenDTO);

        //1.判断请求是否有效
        if (redisService.get(baseToken) == null
                || !redisService.get(baseToken).equals(tokenKey)) {
            log.error("update token info, id is:{}, user info is:{}", baseToken, token);
            throw new TokenErrorException("token错误");
        }

        //2.判断是否需要续期
        if (redisService.getExpireTime(baseToken) < 60 * 3000) {
//            redisService.set(baseToken, tokenKey);
            //设置过期时间8小时
            redisService.setOutTime(baseToken,  60 * 60 * 8 * 1000, TimeUnit.MILLISECONDS);
        }

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}